#include "friend.h"
#include "tcpclient.h"
#include <QInputDialog> //用于输入数据的库
#include <QDebug>
#include "privatechat.h"
#include <qmessagebox.h>
Friend::Friend(QWidget *parent) : QWidget(parent)
{
    m_pShowMsgTE = new QTextEdit;
    m_pFriendListWidget = new QListWidget;
    m_pInputMsgLE = new QLineEdit;
    m_pDelFriendPB = new QPushButton("删除好友");
    m_pFlushFriendPB = new QPushButton("刷新好友");
    m_pShowOnlineUsrPB = new QPushButton("显示在线用户");
    m_pSearchUsrPB = new QPushButton("查找用户");
    m_pMsgSendPB = new QPushButton("信息发送");
    m_pPrivateChatPB = new QPushButton("私聊");
    //建立一个垂直布局
    QVBoxLayout *pRightPBVBL = new QVBoxLayout;
    pRightPBVBL->addWidget(m_pDelFriendPB);
    pRightPBVBL->addWidget(m_pFlushFriendPB);
    pRightPBVBL->addWidget(m_pShowOnlineUsrPB);
    pRightPBVBL->addWidget(m_pSearchUsrPB);
    pRightPBVBL->addWidget(m_pPrivateChatPB);
    //垂直布局
    QHBoxLayout *pTopHBL = new QHBoxLayout;
    pTopHBL->addWidget(m_pShowMsgTE);
    pTopHBL->addWidget(m_pFriendListWidget);
    //按钮放进来，添加布局
    pTopHBL->addLayout(pRightPBVBL);
    //产生一个水平布局用于发送和输入
    QHBoxLayout *pMsgHBL = new QHBoxLayout;
    pMsgHBL->addWidget(m_pInputMsgLE);
    pMsgHBL->addWidget(m_pMsgSendPB);

    m_pOnline = new Online;
    //跟上面的输入框在合成垂直布局
    QVBoxLayout *pMain = new QVBoxLayout;
    pMain->addLayout(pTopHBL);
    pMain->addLayout(pMsgHBL);
    pMain->addWidget(m_pOnline);
    m_pOnline->hide();
    setLayout(pMain);

    connect(m_pShowOnlineUsrPB,SIGNAL(clicked(bool)),this,SLOT(showOnline()));
    connect(m_pSearchUsrPB,SIGNAL(clicked(bool)),this,SLOT(searchUser()));//查找用户这个pushbutton 到searchuser
    connect(m_pFlushFriendPB,SIGNAL(clicked(bool)),this,SLOT(flushFriend()));
    connect(m_pDelFriendPB,SIGNAL(clicked(bool)),this,SLOT(deleteFriend()));
    connect(m_pPrivateChatPB,SIGNAL(clicked(bool)),this,SLOT(privateChate()));
    connect(m_pMsgSendPB,SIGNAL(clicked(bool)),this,SLOT(GroupChat()));
}

void Friend::showAllOnlineUser(PDU *pdu)
{
    if(pdu == nullptr) return;
    m_pOnline->showUser(pdu);//通过client的客户端条件传送过来pdu,通过这里showpdu


}

void Friend::updateFriendList(PDU *pdu)
{
    if(pdu == nullptr) return;
    uint uiSize = pdu->uiMsgLen / 32;//一个人是32个字节，那么用总长度/32就是人数
    char caName[32] = {'\0'};
    for(auto i = 0;i<uiSize;++i)
    {
        memcpy(caName,(char*)(pdu->caMsg) + i *32,32);//将caMsg按照每32个字节为区分传入caName
        m_pFriendListWidget->addItem(caName);
    }

}

void Friend::updateGroupMsg(PDU *pdu)
{
    QString strMsg = QString("%1 says: %2").arg(pdu->caData).arg((char*)pdu->caMsg);//cadata是人的名字，一般是存在cadata,64个字节的长度足够，第二个是发送的消息，额外申请的空间，也就是动态数组
    m_pShowMsgTE->append(strMsg);

}

QListWidget *Friend::getFriendList()
{
    return m_pFriendListWidget;

}
//显示在线用户，通过接入online类，创建的online类的对象来显示出，默认这个显示在线好友窗口是关闭，点击就显示。else就再次关闭。
void Friend::showOnline()
{
    if(m_pOnline->isHidden())
    {
        m_pOnline->show();//在线用户显示
        //请求信息
        PDU *pdu = mkPDU(0);//只是个请求，实际信息不用多申请内存
        pdu->uiMsgType = ENUM_MSG_TYPE_ALLONLINE_REQUEST;
        TcpClient::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
        free(pdu);
        pdu = nullptr;
    }

    else
    {
        m_pOnline->hide();
    }
}

void Friend::searchUser()//查找用户
{
   m_strSearchName =  QInputDialog::getText(this,"搜索","用户名");
   if(!m_strSearchName.isEmpty())
   {
       qDebug() << m_strSearchName;
       PDU *pdu = mkPDU(0);
       memcpy(pdu->caData,m_strSearchName.toStdString().c_str(),m_strSearchName.size());
       pdu->uiMsgType = ENUM_MSG_TYPE_SEARCH_USR_REQUEST;
       TcpClient::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);//通过socket将pdu发送出去
       free(pdu);//发送之后释放掉即可
       pdu = nullptr;
   }
}

void Friend::flushFriend()//刷新好友列表
{
    //获取用户名，通过tcpclient，单例调用
    QString strName = TcpClient::getInstance().loginName();
    PDU *pdu = mkPDU(0);
    pdu->uiMsgType = ENUM_MSG_TYPE_FLUSH_FRIEND_REQUEST;
    memcpy(pdu->caData,strName.toStdString().c_str(),strName.size());//将名字拷贝到了cadata
    TcpClient::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
    free(pdu);
    pdu = nullptr;


}

void Friend::deleteFriend()
{
    //在好友列表选择进行删除
    if(m_pFriendListWidget->currentItem()!=nullptr)
    {
        QString strFriendName =  m_pFriendListWidget->currentItem()->text();//定义一个字符串来获得删除的好友内容
        PDU *pdu = mkPDU(0);
        pdu->uiMsgType = ENUM_MSG_TYPE_DELETE_FRIEND_REQUEST;
        QString strSelfName = TcpClient::getInstance().loginName();//自己的登录的名字
        memcpy(pdu->caData,strSelfName.toStdString().c_str(),strSelfName.size());
        memcpy(pdu->caData+32,strFriendName.toStdString().c_str(),strFriendName.size());
        TcpClient::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);//发送给服务器
        free(pdu);
        pdu = nullptr;
    }

}

void Friend::privateChate()//私聊的槽函数
{
    //点到按钮就显示
    if(m_pFriendListWidget->currentItem()!=nullptr)
    {
        QString strChatName = m_pFriendListWidget->currentItem()->text();
        privateChat::getInstance().setChatName(strChatName);
        if(privateChat::getInstance().isHidden())//隐藏的就显示出来
        {
            privateChat::getInstance().show();
        }
    }
    else
    {
        QMessageBox::warning(this,"私聊","请选择私聊的对象");
    }

}

void Friend::GroupChat()
{
    QString strMsg = m_pInputMsgLE->text();
    if(!strMsg.isEmpty())
    {
        PDU *pdu = mkPDU(strMsg.size() + 1);//1为了放字符串最后的\0
        pdu->uiMsgType = ENUM_MSG_TYPE_GROUP_CHAT_FRIEND_REQUEST;
        QString strName = TcpClient::getInstance().loginName();
        //考虑到loginname 方法得到的是Qstring 类型，所以应该将他转换成string类型然后再获取首地址
        strncpy(pdu->caData,strName.toStdString().c_str(),strName.size());//将loginname传入cadata
        strncpy((char*)(pdu->caMsg),strMsg.toStdString().c_str(),strMsg.size());
        //群聊请求发送给服务器
        TcpClient::getInstance().getTcpSocket().write((char*)pdu,pdu->uiPDULen);
    }
    else
    {
        QMessageBox::warning(this,"群聊","信息不能为空");
    }
}
